package com.gly091020.GLYCan;

import com.gly091020.GLYCan.block.CanBlock;
import com.gly091020.GLYCan.block.entity.CanBlockEntity;
import com.gly091020.GLYCan.util.CanItemContainer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.gametest.framework.*;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.item.DyeItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.PotionContents;
import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.gametest.GameTestHolder;
import net.neoforged.neoforge.gametest.PrefixGameTestTemplate;

import java.util.List;

@GameTestHolder(GLYCanMod.ModID)
public class TestCan {
    private static final BlockPos CAN_POS = new BlockPos(2, 2, 2);

    @GameTest(template = "test_can")
    @PrefixGameTestTemplate(false)
    public static void test_base(GameTestHelper helper){
        var p = helper.makeMockPlayer(GameType.SURVIVAL);
        p.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(Items.GOLDEN_APPLE));
        helper.useBlock(CAN_POS, p);
        helper.assertBlockEntityData(CAN_POS, (entity) -> {
            if(entity instanceof CanBlockEntity entity1){
                return !entity1.isEmpty();
            }
            return false;
        }, () -> "物品放置失败");
        helper.succeed();
    }

    @GameTest(template = "test_can")
    @PrefixGameTestTemplate(false)
    public static void test_input(GameTestHelper helper){
        var p = helper.makeMockPlayer(GameType.SURVIVAL);
        var l = List.of(Items.GOLDEN_APPLE, Items.HONEY_BOTTLE, Items.MILK_BUCKET, Items.APPLE, Items.POTION, Items.TNT);
        for (Item i: l){
            p.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(i));
            if(i == Items.POTION){
                var s = new ItemStack(i);
                s.set(DataComponents.POTION_CONTENTS, new PotionContents(Potions.INVISIBILITY));
                p.setItemInHand(InteractionHand.MAIN_HAND, s);
            }
            helper.useBlock(CAN_POS, p);
            if(i != Items.TNT){
                helper.assertTrue(!p.getInventory().contains(new ItemStack(i, 1)), "物品放置失败");
            }
        }
        helper.assertBlock(new BlockPos(2, 2, 1), block -> block == Blocks.TNT, "放入了不能放的物品");
        helper.succeed();
    }

    @GameTest(template = "test_can")
    @PrefixGameTestTemplate(false)
    public static void test_shift_eat(GameTestHelper helper){
        var p = helper.makeMockPlayer(GameType.SURVIVAL);
        var l = List.of(Items.GOLDEN_APPLE, Items.HONEY_BOTTLE, Items.MILK_BUCKET, Items.APPLE, Items.POTION).reversed();
        for (Item i: l){
            p.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(i));
            if(i == Items.POTION){
                var s = new ItemStack(i);
                s.set(DataComponents.POTION_CONTENTS, new PotionContents(Potions.INVISIBILITY));
                p.setItemInHand(InteractionHand.MAIN_HAND, s);
            }
            helper.useBlock(CAN_POS, p);
        }
        p.setShiftKeyDown(true);
        p.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY);
        for (int i = 0; i < 10; i++) {
            helper.useBlock(CAN_POS, p);
        }
        helper.assertLivingEntityHasMobEffect(p, MobEffects.INVISIBILITY, 0);
        helper.assertTrue(!p.hasEffect(MobEffects.FIRE_RESISTANCE), "牛奶使用失败");
        helper.assertBlockEntityData(CAN_POS, (entity) -> {
            if(entity instanceof CanBlockEntity entity1){
                return entity1.isEmpty();
            }
            return false;
        }, () -> "东西没吃完");
        helper.assertTrue(p.getInventory().contains(new ItemStack(Items.GLASS_BOTTLE, 2)), "玻璃瓶数量错误");
        helper.assertTrue(p.getInventory().contains(new ItemStack(Items.BUCKET, 1)), "未返还桶");
        helper.succeed();
    }

    @GameTest(template = "test_can")
    @PrefixGameTestTemplate(false)
    public static void test_eat(GameTestHelper helper){
        var p = helper.makeMockPlayer(GameType.SURVIVAL);
        var l = List.of(Items.GOLDEN_APPLE, Items.HONEY_BOTTLE, Items.APPLE, Items.POTION).reversed();
        var c = new ItemStack(GLYCanMod.CAN, 1);
        var cc = new CanItemContainer(c);
        for (Item i: l){
            var s = new ItemStack(i);
            if(i == Items.POTION){
                s.set(DataComponents.POTION_CONTENTS, new PotionContents(Potions.INVISIBILITY));
            }
            cc.addItems(s);
        }

        c.finishUsingItem(helper.getLevel(), p);

        helper.assertLivingEntityHasMobEffect(p, MobEffects.INVISIBILITY, 0);
        helper.assertTrue(!p.hasEffect(MobEffects.FIRE_RESISTANCE), "牛奶使用失败");
        helper.assertBlockEntityData(CAN_POS, (entity) -> {
            if(entity instanceof CanBlockEntity entity1){
                return entity1.isEmpty();
            }
            return false;
        }, () -> "东西没吃完");
        helper.succeed();
    }

    @GameTest(template = "test_can")
    @PrefixGameTestTemplate(false)
    public static void test_color(GameTestHelper helper){
        var p = helper.makeMockPlayer(GameType.SURVIVAL);
        var l = List.of(Items.LIGHT_BLUE_DYE, Items.RED_DYE, Items.PINK_DYE, Items.LIME_DYE, Items.ORANGE_DYE);
        for (Item item: l){
            p.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(item, 1));
            helper.useBlock(CAN_POS, p);
        }
        helper.assertBlockEntityData(CAN_POS, (entity) -> {
            if(entity instanceof CanBlockEntity entity1){
                return entity1.color != CanBlock.NORMAL_COLOR;
            }
            return false;
        }, () -> "无法染色");

        p.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(Items.SPONGE, 1));
        helper.useBlock(CAN_POS, p);
        helper.assertBlockEntityData(CAN_POS, (entity) -> {
            if(entity instanceof CanBlockEntity entity1){
                return entity1.color == CanBlock.NORMAL_COLOR;
            }
            return false;
        }, () -> "无法去色");
        helper.succeed();
    }

    @GameTest(template = "test_can")
    @PrefixGameTestTemplate(false)
    public static void test_teto(GameTestHelper helper){
        var p = helper.makeMockPlayer(GameType.SURVIVAL);
        var tomato = BuiltInRegistries.ITEM.get(ResourceLocation.parse("farmersdelight:tomato"));
        var e = helper.getBlockEntity(CAN_POS);
        if(!(e instanceof CanBlockEntity entity)){
            throw new GameTestAssertException("方块实体错误");
        }
        for (int i = 0; i < 10; i++) {
            entity.addItems(new ItemStack(tomato, 1));
        }

        var c = new ItemStack(GLYCanMod.CAN, 1);
        var cc = new CanItemContainer(c);
        for (int i = 0; i < 10; i++) {
            cc.addItems(new ItemStack(tomato, 1));
        }
        p.setItemInHand(InteractionHand.MAIN_HAND, c);
        p.setPos(Vec3.atCenterOf(CAN_POS.above()));
        p.setShiftKeyDown(true);
        p.sendSystemMessage(Component.literal("かさね がさね みる物触れる~"));
        helper.succeed();  // fuck ojang
//        helper.useBlock(CAN_POS, p, new BlockHitResult(Vec3.atCenterOf(helper.absolutePos(CAN_POS)), Direction.DOWN, helper.absolutePos(CAN_POS), true));
//        helper.assertBlockState(CAN_POS.above(), (blockState) -> blockState.getValue(CanBlock.IS_TETO), () -> "堆叠失败");
//        p.sendSystemMessage(Component.literal("かさね がさね みる物触れる~"));
//        helper.succeed();
    }
}
